package com.xiong.wuliao.HomeGame;

import java.util.ArrayList;
import java.util.List;

import org.cocos2d.actions.CCScheduler;
import org.cocos2d.actions.instant.CCCallFunc;
import org.cocos2d.actions.instant.CCCallFuncND;
import org.cocos2d.actions.interval.CCAnimate;
import org.cocos2d.actions.interval.CCMoveTo;
import org.cocos2d.actions.interval.CCSequence;
import org.cocos2d.layers.CCLayer;
import org.cocos2d.nodes.CCAnimation;
import org.cocos2d.nodes.CCDirector;
import org.cocos2d.nodes.CCLabelAtlas;
import org.cocos2d.nodes.CCSprite;
import org.cocos2d.nodes.CCSpriteFrame;
import org.cocos2d.sound.SoundEngine;
import org.cocos2d.types.CGPoint;
import org.cocos2d.types.CGRect;
import org.cocos2d.types.CGSize;
import org.cocos2d.types.util.CGPointUtil;

import android.content.Context;
import android.content.SharedPreferences;
import android.os.Handler;
import android.view.MotionEvent;

import com.xiong.wuliao.R;

public class GameLayout extends CCLayer {

    public Context context;
    private CCSprite background1;
    private CCSprite background2;
    private CGSize winSize;

    private Player player;
    private List<Bullet> playerBullets;
    private List<Enemy> enemies;

    public static final int GAME_RUN = 1;
    public static final int GAME_PAUSE = 2;
    public static final int GAME_OVER = 3;
    public int state = GAME_RUN; //默认游戏状态

    private CGPoint startPoint;
    private CCLabelAtlas labelAtlas;
    private Handler handler;
    private Boolean effectMusic;
    private Boolean bgMusic;

    /**
     * 构造函数
     */
    public GameLayout(Context context, Handler handler) {
        this.context = context;
        this.handler = handler;

        SharedPreferences sharedPreferences = context.getSharedPreferences("game.xml", Context.MODE_PRIVATE);
        effectMusic = sharedPreferences.getBoolean("effectMusic", false);
        bgMusic = sharedPreferences.getBoolean("bgMusic", false);

        playerBullets = new ArrayList<Bullet>();
        enemies = new ArrayList<Enemy>();
        initBackGround();
        schedule("moveBackground");
        initPlayer();
        // 每隔多长时间调用发射子弹方法
        CCScheduler.sharedScheduler().schedule("shoot", this, 0.2f, false);
        // 每隔多长时间调用创建敌机方法
        CCScheduler.sharedScheduler().schedule("makeEnemies", this, 0.5f, false);
        CCScheduler.sharedScheduler().schedule("makebigEnemies", this, 1.5f, false);
        setIsTouchEnabled(true);
        schedule("checkCollosion");
        initLabelScore();
        playSound(R.raw.game_music);
    }

    /**
     * 播放不同的效果音乐
     *
     */
    public void playEffect(int resId) {
        if (effectMusic) {
            SoundEngine.sharedEngine().playEffect(context, resId);
        }
    }

    /**
     * 播放背景音乐
     *
     */
    public void playSound(int resId) {
        if (bgMusic) {
            SoundEngine.sharedEngine().playSound(context, resId, true);
        }
    }

    private void initLabelScore() {
        labelAtlas = CCLabelAtlas.label("0", "myfont.png", 30, 50, '0');
        labelAtlas.setPosition(winSize.width / 5, winSize.height - 80);
        this.addChild(labelAtlas);

    }

    /**
     * 碰撞检测
     */
    public void checkCollosion(float delta) {
        if (state == GAME_RUN) {
            for (Enemy enemy : enemies) {
                // 敌机与玩家碰撞
                if (CGRect.intersects(enemy.getBoundingBox(),
                        player.getBoundingBox())) {
                    // 玩家爆炸
                    playerBomb();
                    playEffect(R.raw.game_over);
                    // 改变游戏状态
                    state = GAME_OVER;
                    //  发送分数到GameActivity中，handler中接受发过来的分数在更新UI，弹出Dialog
                    handler.sendEmptyMessage(player.getScores());
                    // 暂停所有定时器
                    unschedule("moveBackground");
                    unschedule("shoot");
                    unschedule("makeEnemies");
                    unschedule("checkCollosion");

                } else {
                    // 敌机与子弹碰撞
                    for (Bullet bullet : playerBullets) {
                        // 检测子弹是否跟敌机碰撞
                        if (CGRect.intersects(bullet.getBoundingBox(),
                                enemy.getBoundingBox())) {
                            // 计算敌机的生命值
                            float sub = enemy.getLife() - bullet.getAttack();
                            if (sub <= 0) {
                                enemyBomb(enemy);
                                playEffect(R.raw.enemy_down);
                                player.setScores(player.getScores()
                                        + enemy.getScore());
                                labelAtlas.setString(player.getScores() + "");
                            } else {
                                enemy.setLife(sub);
                            }
                            // 当子弹打中敌机时，不管怎样，都会销毁
                            removeBullet(null, bullet);
                        }
                    }
                }
            }
        }
    }

    // 敌机被摧毁
    private void enemyBomb(Enemy enemy) {
        ArrayList<CCSpriteFrame> frames = new ArrayList<CCSpriteFrame>();
        for (int i = 1; i < 6; i++) {
            CCSpriteFrame frame = CCSprite.sprite("enemy01_" + i + ".png")
                    .displayedFrame();
            frames.add(frame);
        }
        CCAnimation animation = CCAnimation.animation("eabomb", frames);
        CCAnimate animate = CCAnimate.action(0.3f, animation, false);
        CCSequence sequence = CCSequence.actions(animate,
                CCCallFuncND.action(this, "removeEnemy", enemy));
        enemy.runAction(sequence);
    }

    // 玩家被摧毁
    private void playerBomb() {
        ArrayList<CCSpriteFrame> frames = new ArrayList<CCSpriteFrame>();
        for (int i = 1; i < 6; i++) {
            CCSpriteFrame frame = CCSprite.sprite("player_" + i + ".png")
                    .displayedFrame();
            frames.add(frame);
        }
        CCAnimation animation = CCAnimation.animation("planebomb", frames);
        CCAnimate animate = CCAnimate.action(0.5f, animation, false);
        CCSequence sequence = CCSequence.actions(animate,
                CCCallFunc.action(this, "destoryPlayer"));
        player.runAction(sequence);
    }

    // 玩家对象销毁方法
    public void destoryPlayer() {
        player.removeSelf();
    }

    /**
     * 创建敌机
     */
    public void makeEnemies(float delta) {

        if (state == GAME_RUN) {
            Enemy enemy = new Enemy("enemy01_1.png");
            enemy.setAnchorPoint(0, 0);
            enemy.setLife(20);
            enemy.setScore(50000);
            enemy.setSpeed(winSize.height * 0.2f);
            // 随机X轴坐标
            float x = (float) (Math.random() * (winSize.width - enemy
                    .getContentSize().width));
            // 随机Y轴坐标
            float y = winSize.height + (float) Math.random()
                    * enemy.getContentSize().height;
            enemy.setPosition(x, y);
            // 添加到敌机集合
            enemies.add(enemy);
            // 添加图层
            this.addChild(enemy);
            // 敌机最终目的地
            CGPoint pos = CGPoint.ccp(enemy.getPosition().x, 0);
            float t = CGPointUtil.distance(enemy.getPosition(), pos)
                    / enemy.getSpeed();
            CCMoveTo moveTo = CCMoveTo.action(t, pos);
            CCCallFunc func = CCCallFuncND.action(this, "removeEnemy", enemy);
            CCSequence sequence = CCSequence.actions(moveTo, func);
            enemy.runAction(sequence);
        }
    }

    public void makebigEnemies(float delta) {

        if (state == GAME_RUN) {
            Enemy enemy = new Enemy("enemy03_1.png");
            enemy.setAnchorPoint(0, 0);
            enemy.setLife(20);
            enemy.setScore(15000);
            enemy.setSpeed(winSize.height * 0.2f);
            // 随机X轴坐标
            float x = (float) (Math.random() * (winSize.width - enemy
                    .getContentSize().width));
            // 随机Y轴坐标
            float y = winSize.height + (float) Math.random()
                    * enemy.getContentSize().height;
            enemy.setPosition(x, y);
            // 添加到敌机集合
            enemies.add(enemy);
            // 添加图层
            this.addChild(enemy);
            // 敌机最终目的地
            CGPoint pos = CGPoint.ccp(enemy.getPosition().x, 0);
            float t = CGPointUtil.distance(enemy.getPosition(), pos)
                    / enemy.getSpeed();
            CCMoveTo moveTo = CCMoveTo.action(t, pos);
            CCCallFunc func = CCCallFuncND.action(this, "removeEnemy", enemy);
            CCSequence sequence = CCSequence.actions(moveTo, func);
            enemy.runAction(sequence);
        }
    }

    /**
     * 敌机销毁
     */
    public void removeEnemy(Object node, Object enemy) {
        enemies.remove(enemy);
        Enemy tempEnemy = (Enemy) enemy;
        tempEnemy.removeSelf();
    }

    /**
     * 点进入游戏，手指触摸屏幕，就会触发以下两个方法
     */
    @Override
    public boolean ccTouchesBegan(MotionEvent event) {
        // 获取触摸点的坐标
        startPoint = convertTouchToNodeSpace(event);
        return super.ccTouchesBegan(event);
    }

    @Override
    public boolean ccTouchesMoved(MotionEvent event) {
        // 获取移动点的坐标
        CGPoint pos = convertTouchToNodeSpace(event);
        float dx = pos.x - startPoint.x;
        float dy = pos.y - startPoint.y;
        float x = player.getPosition().x + dx;
        float y = player.getPosition().y + dy;
        if (x < 0) {
            x = 0;
        } else if (x > winSize.width) {
            x = winSize.width;
        }
        if (y < 0) {
            y = 0;
        } else if (y > winSize.height - player.getContentSize().height) {
            y = winSize.height - player.getContentSize().height;
        }
        player.setPosition(x, y);
        startPoint = pos;
        return super.ccTouchesMoved(event);
    }

    public void shoot(float delta) {
        if (state == GAME_RUN) {
            playerShoot();
        }
    }

    /**
     * 玩家射击子弹
     */
    public void playerShoot() {
        playEffect(R.raw.bullet);// 调用播放子弹的音乐
        Bullet bullet = new Bullet("bullet_blue.png");
        float y = player.getPosition().y + player.getContentSize().height;
        bullet.setPosition(player.getPosition().x, y);
        // 设置子弹攻击值
        bullet.setAttack(50);
        // 设置子弹攻击速度
        bullet.setSpeed(winSize.height * 0.3f);
        // 将子弹添加到集合中
        playerBullets.add(bullet);
        // 添加到图层中
        this.addChild(bullet);
        // 子弹执行位移动画，目的地
        CGPoint pos = CGPoint.ccp(bullet.getPosition().x, winSize.height
                + bullet.getContentSize().height);
        // 执行时间
        float t = CGPointUtil.distance(bullet.getPosition(), pos)
                / bullet.getSpeed();
        CCMoveTo moveTo = CCMoveTo.action(t, pos);
        // 创建回调方法
        CCCallFunc func = CCCallFuncND.action(this, "removeBullet", bullet);
        CCSequence sequence = CCSequence.actions(moveTo, func);
        bullet.runAction(sequence);

    }

    /**
     * 从集合中去掉移出屏幕的子弹，在让它自己销毁掉
     */
    public void removeBullet(Object node, Object bullet) {
        Bullet bullet2 = (Bullet) bullet;
        // 子弹从集合中删除
        playerBullets.remove(bullet2);
        CCSprite temp = (CCSprite) bullet;
        // 自杀
        temp.removeSelf();
    }

    private void initPlayer() {
        // 获取屏幕尺寸对象
        winSize = CCDirector.sharedDirector().winSize();
        player = new Player();
        // 设置飞机锚点在下边缘中间位置
        player.setAnchorPoint(0.5f, 0);
        // 设置飞机位置在屏幕底部中心位置
        player.setPosition(winSize.width / 2, 0);
        this.addChild(player);
    }

    /**
     * 背景移动
     */
    public void moveBackground(float delta) {
        // 每次移动的距离
        float speedBG = 5;
        // 两张背景图以相同的速度向下移动
        background1.setPosition(background1.getPosition().x,
                background1.getPosition().y - speedBG);
        background2.setPosition(background2.getPosition().x,
                background2.getPosition().y - speedBG);
        // 背景2已经移动到原点出现临界情况，就初始化原来背景的位置
        if (background2.getPosition().y <= 0) {
            background1.setPosition(0, 0);
            background2.setPosition(0, background1.getContentSize().height);
        }

    }

    private void initBackGround() {
        // 创建背景对象
        background1 = CCSprite.sprite("background.png");
        background2 = CCSprite.sprite("background.png");
        // 设置锚点
        background1.setAnchorPoint(0, 0);
        background2.setAnchorPoint(0, 0);

        background1.setPosition(0, 0);
        // 背景2在背景1上面
        background2.setPosition(0, background1.getContentSize().height);

        this.addChild(background1);
        this.addChild(background2);
    }

}
